package com.jushu.storbox.util;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/*
 * AES
 * */
public class AESEncryptorUtil {
	
	//AES
	private final static String HEX = "0123456789ABCDEF";
	private final static String AES = "AES";
	private final static String AES_TYPE = "AES/CBC/PKCS5Padding";
	private final static String SHALPRNG = "SHA1PRNG";
	private final static int KEY_SIZE = 128;//
	
	
	public static final String VIPARA = "0102030405060708";  
	public static final String bm = "GBK";
	

    public static String encryptAndBase64(String dataPassword, String cleartext)  
    throws Exception {  
		IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes());  
		SecretKeySpec key = new SecretKeySpec(dataPassword.getBytes(), "AES");  
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");  
		cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);  
		byte[] encryptedData = cipher.doFinal(cleartext.getBytes(bm));  
		return Base64Util.encode(encryptedData);  
	}  
	
	public static String decryptAndBase64(String dataPassword, String encrypted)  
	    throws Exception {  
		byte[] byteMi = Base64Util.decode(encrypted);  
		IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes());  
		SecretKeySpec key = new SecretKeySpec(dataPassword.getBytes(), "AES");  
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");  
		cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);  
		byte[] decryptedData = cipher.doFinal(byteMi);  
		return new String(decryptedData,bm);  
	} 

    public static String getSpesPwd() throws NoSuchAlgorithmException, UnsupportedEncodingException {
    	return "0ac11b3c4dgassl3";
     }

    
    public static String encrypt(String seed, String cleartext) throws Exception {  
        byte[] rawKey = getRawKey(seed.getBytes());  
        byte[] result = encrypt(rawKey, cleartext.getBytes());  
        return toHex(result);  
    }  
      

    private static String decrypt(String seed, String encrypted) throws Exception {  
        byte[] rawKey = getRawKey(seed.getBytes());  
        byte[] enc = toByte(encrypted);  
        byte[] result = decrypt(rawKey, enc);  
        return new String(result);  
    }  

    private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {  
        SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);  
        Cipher cipher = Cipher.getInstance(AES_TYPE);  
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec,new IvParameterSpec(new byte[cipher.getBlockSize()]));  
        byte[] encrypted = cipher.doFinal(clear);  
        return encrypted;  
    }  
 
    private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {  
        SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);  
        Cipher cipher = Cipher.getInstance(AES_TYPE);  
        cipher.init(Cipher.DECRYPT_MODE, skeySpec,new IvParameterSpec(new byte[cipher.getBlockSize()]));  
        byte[] decrypted = cipher.doFinal(encrypted);  
        return decrypted;  
    }  
    
    public static byte[] md5(byte[] src) throws NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("MD5");
        digest.update(src);
        byte[] md5 = digest.digest();
        return md5;
     }

    private static byte[] getRawKey(byte[] seed) throws Exception {  
        KeyGenerator kgen = KeyGenerator.getInstance(AES);  
        SecureRandom sr = SecureRandom.getInstance(SHALPRNG);  
        sr.setSeed(seed);  
        kgen.init(KEY_SIZE, sr); // 192 and 256 bits may not be available  
        SecretKey skey = kgen.generateKey();  
        byte[] raw = skey.getEncoded();  
        return raw;  
    }  
 
    public static String toHex(String txt) {  
        return toHex(txt.getBytes());  
    }  
    public static String fromHex(String hex) {  
        return new String(toByte(hex));  
    }  
      
    public static byte[] toByte(String hexString) {  
        int len = hexString.length()/2;  
        byte[] result = new byte[len];  
        for (int i = 0; i < len; i++)  
            result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();  
        return result;  
    }  
 
    public static String toHex(byte[] buf) {  
        if (buf == null)  
            return "";  
        StringBuffer result = new StringBuffer(2*buf.length);  
        for (int i = 0; i < buf.length; i++) {  
            appendHex(result, buf[i]);  
        }  
        return result.toString();  
    }  
    private static void appendHex(StringBuffer sb, byte b) {  
        sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));  
    }  
}
